import ujson
import os
import threading
import sqlite3

# 移除原有的 data_root 定义
# data_root = os.path.abspath(os.path.join(os.path.dirname(__file__), 'data'))

# 定义数据库文件路径
db_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), 'data'))
os.makedirs(db_dir, exist_ok=True)
db_path = os.path.abspath(os.path.join(db_dir, 'data.db'))

lock = threading.Lock()

def get_id(ip, port):
    temp = ip.split('.')
    padded_ip = []
    for item in temp:
        item: str
        padded_ip.append(item.rjust(3, '0'))
    return '%s#%s' % ('.'.join(padded_ip), str(port).rjust(5, '0'))

# 初始化数据库
def init_db():
    with sqlite3.connect(db_path) as conn:
        cursor = conn.cursor()
        cursor.execute('''
            CREATE TABLE IF NOT EXISTS info (
                id TEXT PRIMARY KEY,
                name TEXT,
                ip TEXT,
                port INTEGER,
                alive BOOLEAN,
                delay INTEGER,
                timestamp DATETIME
            )
        ''')
        conn.commit()

init_db()

class Info:
    def __init__(self):
        self.id = ''
        self.name = ''
        self.ip = ''
        self.port = 0
        self.alive = False
        self.delay = -1
        self.timestamp = None

    def to_dict(self):
        return {
            'id': self.id,
            'name': self.name,
            'ip': self.ip,
            'port': self.port,
            'alive': self.alive,
            'delay': self.delay,
            'timestamp': self.timestamp
        }

    def from_dict(self, data):
        self.id = data['id']
        self.name = data['name']
        self.ip = data['ip']
        self.port = data['port']
        self.alive = data['alive']
        self.delay = data.get('delay', -1)
        self.timestamp = data['timestamp']
        return self

    @staticmethod
    def load(id):
        try:
            with sqlite3.connect(db_path) as conn:
                cursor = conn.cursor()
                cursor.execute('SELECT * FROM info WHERE id = ?', (id,))
                row = cursor.fetchone()
                if row:
                    info = Info()
                    info.id = row[0]
                    info.name = row[1]
                    info.ip = row[2]
                    info.port = row[3]
                    info.alive = bool(row[4])
                    info.delay = row[5]
                    info.timestamp = row[6]
                    return info
                else:
                    return None
        except Exception as ex:
            raise Exception(f'Failed to load data for id {id}: {str(ex)}')

    def dump(self):
        try:
            lock.acquire()
            with sqlite3.connect(db_path) as conn:
                cursor = conn.cursor()
                cursor.execute('''
                    INSERT OR REPLACE INTO info 
                    (id, name, ip, port, alive, delay, timestamp)
                    VALUES (?, ?, ?, ?, ?, ?, ?)
                ''', (
                    self.id, self.name, self.ip, self.port,
                    self.alive, self.delay, self.timestamp
                ))
                conn.commit()
        finally:
            lock.release()

    def refresh(self):
        from worker import test_one
        test_one(self)
        self.dump()

    def delete(self):
        try:
            lock.acquire()
            with sqlite3.connect(db_path) as conn:
                cursor = conn.cursor()
                cursor.execute('DELETE FROM info WHERE id = ?', (self.id,))
                conn.commit()
        finally:
            lock.release()

class Result:
    def __init__(self):
        self.code = 0
        self.msg = ''
        self.data = None

    def to_dict(self):
        return {
            'code': self.code,
            'msg': self.msg,
            'data': self.data
        }

    @staticmethod
    def ok(data):
        result = Result()
        result.code = 200
        result.msg = 'ok'
        result.data = data
        return result.to_dict()

    @staticmethod
    def bad(msg):
        result = Result()
        result.code = 400
        result.msg = msg
        return result.to_dict()

def load_list(to_dict=False):
    result = []
    try:
        with sqlite3.connect(db_path) as conn:
            cursor = conn.cursor()
            cursor.execute('SELECT * FROM info order by id')
            rows = cursor.fetchall()
            for row in rows:
                info = Info()
                info.id = row[0]
                info.name = row[1]
                info.ip = row[2]
                info.port = row[3]
                info.alive = bool(row[4])
                info.delay = row[5]
                info.timestamp = row[6]
                result.append(info.to_dict() if to_dict else info)
    except Exception as ex:
        raise Exception(f'Failed to load list: {str(ex)}')
    return result

def ip_to_int(ip):
    parts = ip.split('.')
    result = 0
    for i in range(4):
        result += int(parts[i]) << (8 * (3 - i))
    return result
